﻿using System;
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;

public enum IconStartType
{
    Init,
    Default,
    Flip,
    Collision,
    Show
}
public class Icon : MonoBehaviour
{
    private static readonly Vector3 MAX_SIZE =new Vector3(3, 3, 1);
    public const float TIME_DURATION = 0.75f;

    private static CircleCollider2D _toch;
    public static readonly List<Icon> Icons = new List<Icon>();

    private SpriteRenderer _iconUI;
    private SpriteRenderer _bgUI;

    private Vector3 _startPos;
    private Rigidbody2D _rig;
    private IconStartType _state;

    private readonly List<Tween> _tweens = new List<Tween>();
    public IconStartType State
    {
        set
        {
            Debug.Log(value);
            switch (value)
            {
                case IconStartType.Init:
                    ToInitState();
                    break;
                case IconStartType.Default:
                    ToDefaultState();
                    break;
                case IconStartType.Flip:
                    ToFlipState();
                    break;
                case IconStartType.Collision:
                    ToCollisionState();
                    break;
                case IconStartType.Show:
                    ToShowState();
                    break;
            }
        }
        get { return _state; }
    }

    private void ToInitState()
    {
        _state = IconStartType.Init;
        if (_collider2D != null)
        {
            _collider2D.enabled = false;
            _collider2D.radius = 0.0001f;
        }
        KillAllTweens();
        _rig.constraints = RigidbodyConstraints2D.FreezeAll;
        NewTween = _iconUI.transform.DOLocalRotate(new Vector3(0, 180, 0), TIME_DURATION);
        NewTween = transform.DOLocalMove(_startPos, TIME_DURATION);
        NewTween = transform.DOLocalRotate(Vector3.zero, TIME_DURATION);
        NewTween = transform.DOScale(Vector3.one, TIME_DURATION);
    }

    private void ToDefaultState()
    {
        _state = IconStartType.Default;
        if (_collider2D != null)
        {
            _collider2D.enabled = false;
            _collider2D.radius = 0.0001f;
        }
        KillAllTweens();
        _rig.constraints = RigidbodyConstraints2D.FreezeAll;
        NewTween = _iconUI.transform.DOLocalRotate(new Vector3(0, 0, 0), TIME_DURATION);
        NewTween = transform.DOLocalMove(_startPos, TIME_DURATION);
        NewTween = transform.DOLocalRotate(Vector3.zero, TIME_DURATION);
        NewTween = transform.DOScale(Vector3.one, TIME_DURATION);
    }

    private void ToFlipState()
    {
        _state = IconStartType.Flip;
        KillAllTweens();
        if (_collider2D != null)
        {
            _collider2D.enabled = false;
            _collider2D.radius = 0.0001f;
        }
        _rig.constraints = RigidbodyConstraints2D.FreezeAll;
        NewTween = _iconUI.transform.DOLocalRotate(Vector3.zero, TIME_DURATION);
        NewTween = transform.DOLocalMove(_startPos, TIME_DURATION);
        NewTween = transform.DOLocalRotate(Vector3.zero, TIME_DURATION);
        NewTween = transform.DOScale(Vector3.one, TIME_DURATION);
    }


    private void ToShowState()
    {
        _state = IconStartType.Show;
        if (_collider2D != null)
        {
            _collider2D.enabled = true;
            _collider2D.radius = 0.0001f;
        }
        else
        {
            _collider2D = gameObject.AddComponent<CircleCollider2D>();
            _collider2D.enabled = true;
            _collider2D.radius = 0.0001f;
        }
        KillAllTweens();
        _rig.constraints = RigidbodyConstraints2D.FreezeAll;
        NewTween = _iconUI.transform.DOLocalRotate(Vector3.zero, TIME_DURATION);
        NewTween = transform.DOLocalMove(_startPos, TIME_DURATION);
        NewTween = transform.DOLocalRotate(Vector3.zero, TIME_DURATION);
        NewTween = transform.DOScale(MAX_SIZE, TIME_DURATION);
        NewTween = DOTween.To(() => 0f, radius =>
        {
            _collider2D.radius = radius;
        }, 4f, TIME_DURATION*0.75f).OnComplete(() =>
        {
            _collider2D.enabled = false;
            _collider2D.radius = 0.0001f;
        });
    }
    private void ToCollisionState()
    {
        _state = IconStartType.Collision;
        if (_collider2D != null)
        {
            _collider2D.enabled = false;
            _collider2D.radius = 0.0001f;
        }
        _rig.constraints = RigidbodyConstraints2D.None;
        transform.DOKill();
        NewTween = transform.DOScale(new Vector3(0.75f, 0.75f, 1), TIME_DURATION);
    }
    private Tween NewTween
    {
        set { _tweens.Add(value); }
    }
    private void KillAllTweens()
    {
        if (_tweens.Count > 0)
        {
            for (int i = 0; i < _tweens.Count; ++i)
            {
                if (_tweens[i].IsPlaying())
                {
                    _tweens[i].Kill();
                }
            }
            _tweens.Clear();
        }
    }

    private Action _callback;
    public void Init(Sprite icon, Sprite bg,Vector2 pos,Action callback)
    {
        _callback = callback;
        gameObject.layer = LayerMask.NameToLayer("Logo");
        if (_toch == null)
        {
            _toch = new GameObject("Toch").AddComponent<CircleCollider2D>();
            _toch.enabled = false;
            _toch.radius = 0.0001f;
            _toch.isTrigger = true;
        }
        Icons.Add(this);
        gameObject.AddComponent<BoxCollider2D>();
        _rig = gameObject.AddComponent<Rigidbody2D>();
        _rig.gravityScale = 0.15f;
        _rig.constraints = RigidbodyConstraints2D.FreezeAll;
        _iconUI = new GameObject("icon").AddComponent<SpriteRenderer>();
        _bgUI = new GameObject("bg").AddComponent<SpriteRenderer>();
        _iconUI.transform.SetParent(transform);
        _iconUI.transform.localPosition = new Vector3(0, 0, -0.001f);
        _bgUI.transform.SetParent(_iconUI.transform);
        _bgUI.transform.localPosition = new Vector3(0, 0, 0.001f);
        _iconUI.sprite = icon;
        _bgUI.sprite = bg;
        _startPos = transform.localPosition = pos;
        _iconUI.transform.localEulerAngles = new Vector3(0, 180, 0);
    }

    public void Play()
    {
        if (State == IconStartType.Init)
        {
            State = IconStartType.Default;
            StartCoroutine(DoPlay());
        }
    }
    private IEnumerator DoPlay()
    {
        yield return new WaitForSeconds(2);
        if (State == IconStartType.Default)
        {
            State = IconStartType.Init;
        }
    }

    private void OnDrawGizmos()
    {
        var matrix = Gizmos.matrix;
        Gizmos.matrix = transform.localToWorldMatrix;
        switch (State)
        {
            case IconStartType.Init:
                Gizmos.color = Color.white;
                break;
            case IconStartType.Default:
                Gizmos.color = Color.yellow;
                break;
            case IconStartType.Flip:
                Gizmos.color = Color.green;
                break;
            case IconStartType.Collision:
                Gizmos.color = Color.red;
                break;
            case IconStartType.Show:
                Gizmos.color = Color.blue;
                break;
        }
        Gizmos.DrawWireCube(Vector3.zero, Vector3.one);
        Gizmos.matrix = matrix;
    }

    private CircleCollider2D _collider2D;

    public static void ToAllInitState()
    {
        for (int i = 0; i < Icons.Count; ++i)
        {
            Icons[i].State = IconStartType.Init;
        }
        _toch.enabled = false;
        _toch.radius = 0.0001f;
        _toch.isTrigger = true;
    }

    private void ToFlip()
    {
        State = IconStartType.Flip;
        _toch.name = name;
        _toch.enabled = true;
        _toch.transform.position = transform.position + new Vector3(0, 0, 1);
        DOTween.To(() => 0.0001f, radius =>
        {
            _toch.radius = radius;
        }, 17f, TIME_DURATION * 3).OnComplete(() =>
        {
            _toch.enabled = false;
            _toch.radius = 0.0001f;
            _toch.isTrigger = true;
        });
    }
    public void MouseDown()
    {
        switch (State)
        {
            case IconStartType.Init:
            case IconStartType.Default:
                ToFlip();
                break;
            case IconStartType.Flip:
                ToShow();
                break;
            case IconStartType.Show:
                _callback();
                //ToAllInitState();
                break;
        }
    }

    private void ToShow()
    {
        for (int i = 0; i < Icons.Count;++i)
        {
            if (Icons[i] == this)
            {
                Icons[i].State = IconStartType.Show;
            }
            else
            {
                Icons[i].State = IconStartType.Collision;
            }
        }
    }
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (State == IconStartType.Default || State == IconStartType.Init)
        {
            State = IconStartType.Flip;
        }else if (State == IconStartType.Collision)
        {
            NewTween = _iconUI.transform.DOLocalRotate(Vector3.zero, TIME_DURATION);
        }
    }
}